<template>
	<div>
		<el-dialog v-model="dialogFormVisible"
							 :before-close="handlerBeforeClose"
							 :title="dbType" width="700px">
			<el-form
				ref="ruleFormRef"
				:model="form"
				:rules="rules"
				:label-position="labelPosition"
				:label-width="formLabelWidth"
			>
				<el-row>
					<el-col :span="12">
						<el-form-item label="连接名称" prop="dsName">
							<el-input v-model="form.dsName" autocomplete="off"/>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="连接类型" prop="dsType">
							<el-input v-model="form.dsType" disabled/>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item label="主机" prop="host">
							<el-input v-model="form.host"/>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="端口号" prop="port">
							<el-input v-model="form.port"/>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item label="用户名" prop="username">
							<el-input v-model="form.username"/>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="密码" prop="password">
							<el-input v-model="form.password" show-password/>
						</el-form-item>
					</el-col>
				</el-row>
				<el-row>
					<el-col :span="12">
						<el-form-item label="数据库" prop="dsDataBase">
							<el-input v-model="form.dsDataBase"/>
						</el-form-item>
					</el-col>
					<el-col :span="12">
						<el-form-item label="当前schema" v-if="dbType==='oracle'">
							<el-input v-model="form.dsSchema"/>
						</el-form-item>
					</el-col>
				</el-row>

				<el-form-item label="驱动" prop="driverJarPath">
					<el-select v-model="form.driverJarPath" placeholder="请选择驱动jar"
										 style="width: 100%" clearable filterable>
						<el-option
							v-for="item in jarList"
							:key="item.uploadFile"
							:label="item.fileName"
							:value="item.uploadFile"
						/>
					</el-select>
				</el-form-item>
				<el-form-item label="驱动类" prop="driverClassName">
					<el-input v-model="form.driverClassName"/>
					<p style="color: rgb(218, 220, 225)"> 例如: com.mysql.cj.jdbc.Driver</p>
				</el-form-item>
				<el-form-item label="驱动属性" prop="driverUrlExtendProperties">
					<el-input v-model="form.driverUrlExtendProperties" type="textarea" :autosize="{ minRows: 2, maxRows: 10 }"/>
					<p style="color: rgb(218, 220, 225)"> 指定数据库的其他链接配置key1=value1&key2=value2</p>
				</el-form-item>

				<el-form-item label="连接描述">
					<el-input v-model="form.dsDescribe" type="textarea" :autosize="{ minRows: 2, maxRows: 10 }"/>
				</el-form-item>
				<div>
					<el-row>
						<el-col :span="2" :offset="1">
							<el-button type="plain" link @click="handlerDownDriver" v-if="downDriverBtnShow">下载驱动</el-button>
							<p style="color: rgb(218, 220, 225)">{{ downDriverMessage }}</p>
						</el-col>
						<el-col :span="3" :offset="18">
							<el-upload
								class="upload-demo"
								:show-file-list="false"
								action=""
								multiple
								:limit="1"
								:on-change="handlerOnChange"
								:before-upload="handlerBeforeFileUpload"
								:auto-upload="false"
							>
								<el-button type="primary" link>上传驱动</el-button>
							</el-upload>
							<p style="color: rgb(218, 220, 225)">{{ uploadDriverMessage }}</p>
						</el-col>
					</el-row>
				</div>
			</el-form>
			<template #footer>
				<el-row :gutter="20">
					<el-col :span="2">
						<el-button @click="testConnection">测试连接</el-button>
					</el-col>
					<el-col :span="10"></el-col>
					<el-col :span="12">
						<el-button type="primary" @click="handlerOnClick(ruleFormRef)">
							确定
						</el-button>
						<el-button @click="handlerCancel">取消</el-button>
					</el-col>
				</el-row>

			</template>
		</el-dialog>
	</div>
</template>

<script setup>
import {reactive, ref, toRefs} from 'vue'
import {saveDs, updateDs, checkDsConnection, uploadDriver, downDriver, queryJarList} from '@/service/api/resource';
import {useMessage} from "naive-ui";

const msg = useMessage()

const emit = defineEmits((['fetch-data']))

const labelPosition = ref('right')

const formLabelWidth = ref('100px')

const dialogFormVisible = ref(false)
const ruleFormRef = ref()
const dbType = ref()

const downDriverMessage = ref('')
const downDriverBtnShow = ref(true)

const uploadDriverMessage = ref('')

const jarList = ref([])


const state = reactive({
	form: {
		dsName: '',
		dsType: '',
		host: '',
		port: '',
		dsDataBase: '',
		username: '',
		password: '',
		dsSchema: '',
		driverClassName: '',
		driverUrlExtendProperties: '',
		dsDescribe: '',
		driverJarPath: ''
	},
	rules: {
		dsName: [
			{
				required: true,
				message: '请输入连接名',
				trigger: 'change',
			},
		],
		dsType: [
			{
				required: true,
				message: '请选择用户类型',
				trigger: 'change',
			},
		],
		host: [
			{
				required: true,
				message: '请输入主机地址',
				trigger: 'change',
			},
		],
		port: [
			{
				required: true,
				message: '请输入端口号',
				trigger: 'change',
			},
		],
		username: [
			{
				required: true,
				message: '请输入用户名称',
				trigger: 'change',
			},
		],
		password: [
			{
				required: true,
				message: '请输入用户密码',
				trigger: 'change',
			},
		],
		dsDataBase: [
			{
				required: true,
				message: '请输入数据库',
				trigger: 'change',
			},
		],
		driverClassName: [
			{
				required: true,
				message: '请输入驱动类名称',
				trigger: 'change',
			},
		],
		driverJarPath: [
			{
				required: true,
				message: '请选择驱动',
				trigger: 'change',
			},
		]
	}
})
const {form, rules} = toRefs(state)

const openDialog = (dsType) => {
	dbType.value = dsType
	dialogFormVisible.value = true
	downDriverBtnShow.value = true
	downDriverMessage.value = ''
	uploadDriverMessage.value = ''
	state.form.dsType = dbType.value
	initJars()
	resetFields()
	ruleFormRef.value.clearValidate()
}
const editOpenDialog = (row) => {
	dialogFormVisible.value = true
	dbType.value = row.dsType
	initJars()
	resetFields(row)
	downDriverBtnShow.value = false
}
const handlerBeforeClose = () => {
	ruleFormRef.value.resetFields()
	ruleFormRef.value.clearValidate()
	dialogFormVisible.value = false
}


const handlerCancel = () => {
	ruleFormRef.value.resetFields()
	ruleFormRef.value.clearValidate()
	dialogFormVisible.value = false
}


const handlerDownDriver = () => {
	downDriver(dbType.value).then(res => {
		const {data} = res
		initJars()
		downDriverBtnShow.value = false
		state.form.driverJarPath = data.uploadPath
		state.form.driverClassName = data.driverClassName
		downDriverMessage.value = '下载成功'
	})

}

const handlerBeforeFileUpload = (rawFile) => {
	if (rawFile.type !== 'jar') {
		msg.error('文件必须为jar包')
		return false
	}
	return true
}

const handlerOnChange = (file) => {
	// 这一步进行上传驱动,上传成功后得到上传的路径以及填充driverClassName
	let formData = new FormData();
	formData.append("dsType", dbType.value)
	formData.append("file", file.raw)
	uploadDriver(formData).then(res => {
		const {data} = res;
		initJars()
		state.form.driverJarPath = data.uploadPath
		state.form.driverClassName = data.driverClassName
		uploadDriverMessage.value = '上传成功'
	})
}

const testConnection = () => {
	checkDsConnection(state.form).then(res => {
		if (res.data === true) {
			msg.success("连接成功");
		} else {
			msg.error("连接失败")
		}
	})
}


const handlerOnClick = (formEl) => {
	formEl.validate((valid, fields) => {
		if (valid) {
			if (state.form.dsId) {
				updateDs(state.form).then(res => {
					emit('fetch-data')
					dialogFormVisible.value = false
				}).catch(error => {
					msg.error(error.message);
				})
			} else {
				saveDs(state.form).then(res => {
					emit('fetch-data')
					dialogFormVisible.value = false
				}).catch(error => {
					msg.error(error.message);
				})
			}
		} else {
			console.log('error submit!', fields)
		}
	})

}

const initJars = () => {
	queryJarList(dbType.value).then(res => {
		const {data} = res;
		jarList.value = data;
	})
}


defineExpose({
	openDialog,
	editOpenDialog
})


const resetFields = (row) => {
	if (row) {
		state.form.dsId = row.dsId
		state.form.dsType = row.dsType
		state.form.host = row.host
		state.form.port = row.port
		state.form.dsDataBase = row.dsDataBase
		state.form.dsName = row.dsName
		state.form.username = row.username
		state.form.password = row.password
		state.form.driverClassName = row.driverClassName
		state.form.driverUrlExtendProperties = row.driverUrlExtendProperties
		state.form.driverJarPath = row.driverJarPath
		state.form.dsDescribe = row.dsDescribe
	} else {
		state.form.dsId = ''
		state.form.dsName = ''
		state.form.host = ''
		state.form.port = ''
		state.form.dsDataBase = ''
		state.form.username = ''
		state.form.password = ''
		state.form.driverClassName = ''
		state.form.driverUrlExtendProperties = ''
		state.form.driverJarPath = ''
		state.form.dsDescribe = ''
	}
}
</script>

<style scoped>

</style>
